package com.liukaixin.product.ru.business.team.teamdesc;

import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.liukaixin.product.ru.Injection;
import com.liukaixin.product.ru.data.CallBackListener;
import com.liukaixin.product.ru.data.model.Apply;
import com.liukaixin.product.ru.data.model.Competition;
import com.liukaixin.product.ru.data.model.Favorite;
import com.liukaixin.product.ru.data.model.Result;
import com.liukaixin.product.ru.data.model.Team;
import com.liukaixin.product.ru.data.model.TeamMember;
import com.liukaixin.product.ru.data.repositories.TeamsRepository;
import com.liukaixin.product.ru.data.repositories.UserRepository;
import com.liukaixin.product.ru.enumerate.ApplyStatusEnum;
import com.orhanobut.logger.Logger;

import java.util.List;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Created by Jacob on 2016/9/19.
 */
public class TeamDescPresenter implements TeamDescContract.Presenter {
    @NonNull
    private final TeamsRepository teamsRepository;

    @NonNull
    private final TeamDescContract.View teamDescView;

    private Handler handler = new Handler();

    @NonNull
    private Integer teamId;

    public TeamDescPresenter(Integer teamId, TeamsRepository teamsRepository,
                             TeamDescContract.View teamDescView) {
        this.teamId = teamId;
        this.teamsRepository = teamsRepository;
        this.teamDescView = teamDescView;

        this.teamDescView.setPresenter(this);
    }

    /**
     * 获取团队详情.
     * <p>
     * 流程:
     * (1)显示加载框
     * (2)加载完成后隐藏加载框
     * (3)加载错误时显示错误视图
     * (4)加载成功显示scrollView,显示数据.
     */
    @Override
    public void getTeamDescById() {
        Logger.d("执行获取团队详情任务,teamId = %d", teamId);
        teamDescView.showLoading();
        teamsRepository.getTeamDescById(teamId,
                new CallBackListener<Team>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(String msg) {
                        teamDescView.hideLoading();
                        teamDescView.showErrorToast(msg);
                    }

                    @Override
                    public void onNext(Team team) {
                        teamDescView.hideLoading();
                        teamDescView.showScrollView();
                        teamDescView.setTeam(team);
                        teamDescView.showData(team);
                        teamDescView.getTeamMembers();
                    }
                });
    }

    /**
     * 判断是否申请加入过该团队.
     * <p>
     * 流程:
     * (1)加载完成什么都不做.
     * (2)加载出错,重新请求.
     * (3)加载成功,如果已经申请过,则显示已提申请按钮,否则显示申请加入按钮.
     *
     * @param applyUserId 申请人id
     */
    @Override
    public void getApplyStatus(Integer applyUserId) {
        Logger.d("判断用户提交加入申请的情况,Team id = %d, userId = %d", teamId, applyUserId);
        teamsRepository.getApplyStatus(teamId, applyUserId, new CallBackListener<Integer>() {
            @Override
            public void onCompleted() {
                // do nothing
            }

            @Override
            public void onError(String msg) {
                teamDescView.showErrorToast(msg);
            }

            @Override
            public void onNext(Integer status) {
                teamDescView.showPlusTab(status);
            }
        });
    }

    /**
     * 发送请求.
     * <p>
     * 流程:
     * (1)处理请求过程中按钮禁止点击
     * (2)完成后按钮可点击
     * (3)出错显示错误信息
     * (4)成功显示已提申请按钮.
     *
     * @param apply 请求
     */
    @Override
    public void sendApply(Apply apply) {
        teamDescView.showLoading();
        teamsRepository.sendAbility(apply,
                new CallBackListener<String>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(String msg) {
                        teamDescView.hideLoading();
                        teamDescView.showErrorToast(msg);
                    }

                    @Override
                    public void onNext(String s) {
                        teamDescView.hideLoading();
                        teamDescView.showPlusTab(TeamDescFragment.CHECK);
                    }
                });
    }

    /**
     * 获得其他团队的申请状态,如果该用户已被其他团队录用,则不能再申请新团队.
     * <p>
     * 流程:
     * (1)显示加载,按钮禁止点击,加载完成后隐藏加载
     * (2)加载错误,什么也不做
     * (3)加载成功,让申请加入按钮可点击
     * 如果被其他团队加入,则提示不能再申请该团队,并将已被加入设置为1,防止重复请求
     * 如果没有,则判断个人信息是否完整
     *
     * @param applyUserId     申请人的id(存在本机的id)
     * @param competitionName 申请的比赛的名称
     */
    @Override
    public void getOtherApplyStatus(Integer applyUserId, String competitionName) {
        teamDescView.showLoading();
        teamsRepository.getOtherApplyStatus(applyUserId, competitionName,
                new CallBackListener<Integer>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(String msg) {
                        teamDescView.hideLoading();
                        teamDescView.showErrorToast(msg);
                    }

                    @Override
                    public void onNext(Integer status) {
                        teamDescView.hideLoading();
                        if (!status.equals(ApplyStatusEnum.AGREE.getTypeCode())) {
                            teamDescView.checkPersonalInfo();
                        } else {
                            teamDescView.haveAgreeByOthers();
                        }
                    }
                });
    }

    /**
     * 获取收藏状态.
     * <p>
     * 流程:
     * (1)获取完成后让收藏按钮变为可点击状态.
     * (2)获取错误后什么也不做.
     * (3)获取成功,如果收藏,则显示收藏状态,否则,则显示为收藏状态.
     *
     * @param userId 用户id
     */
    @Override
    public void getFavoriteStatus(Integer userId) {
        UserRepository userRepository = Injection.provideUserRepository();
        userRepository.getFavoriteStatusByStarIdAndUserId(
                teamId, userId, new CallBackListener<Boolean>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(String msg) {
                        // do nothing
                        teamDescView.showErrorToast(msg);
                    }

                    @Override
                    public void onNext(Boolean result) {
                        if (result) {
                            teamDescView.makeFavorited();
                        } else {
                            teamDescView.makeUnFavorited();
                        }
                    }
                });
    }

    /**
     * 判断是不是自己的团队.
     * <p>
     * 流程:
     * (1)如果是自己的团队,则显示"审核申请"按钮
     * (2)如果不是自己的团队,则获取申请状态
     *
     * @param creatorId 团队创建者id
     * @param userId    用户id
     */
    @Override
    public void whoseTeam(@NonNull Integer creatorId, @NonNull Integer userId) {
        checkNotNull(creatorId);
        checkNotNull(userId);
        if (creatorId.equals(userId)) {
            Logger.d("是自己的团队");
            // 显示"审核申请"按钮
            teamDescView.showPlusTab(TeamDescFragment.CHECK_APPLY);
        } else {
            Logger.d("不是自己的团队");
            // 获取申请
            getApplyStatus(userId);
        }
    }

    /**
     * 收藏团队.
     * <p>
     * 流程:
     * (1)显示已收藏,收藏按钮不可点击.
     * (2)加载完成后,收藏按钮可点击.
     * (3)加载错误后,什么也不做.
     * (4)加载成功,什么也不做.
     *
     * @param favorite 收藏
     */
    @Override
    public void doFavorite(Favorite favorite) {
        teamDescView.showLoading();
        UserRepository userRepository = Injection.provideUserRepository();

        userRepository.favorite(favorite, new CallBackListener<Result<String>>() {
            @Override
            public void onCompleted() {
                // do nothing
            }

            @Override
            public void onError(String msg) {
                teamDescView.hideLoading();
                teamDescView.showErrorToast(msg);
            }

            @Override
            public void onNext(Result<String> result) {
                teamDescView.hideLoading();
                teamDescView.makeFavorited();
            }
        });
    }

    /**
     * 取消收藏团队.
     * <p>
     * 流程:
     * (1)显示已取消收藏按钮不可点击.
     * (2)加载完成后,收藏按钮可点击.
     * (3)加载错误后,什么也不做.
     * (4)加载成功,什么也不做.
     *
     * @param userId 用户id
     */
    @Override
    public void cancelFavorite(Integer userId) {
        teamDescView.showLoading();
        UserRepository userRepository = Injection.provideUserRepository();
        userRepository.cancelFavorite(teamId, userId,
                new CallBackListener<Result<String>>() {
                    @Override
                    public void onCompleted() {
                        // do nothing
                    }

                    @Override
                    public void onError(String msg) {
                        teamDescView.hideLoading();
                        teamDescView.showErrorToast(msg);
                    }

                    @Override
                    public void onNext(Result<String> result) {
                        teamDescView.hideLoading();
                        teamDescView.makeUnFavorited();
                    }
                });
    }

    @Override
    public void getTeamMembers(Integer teamId) {
        teamsRepository.getTeamMembers(teamId, new CallBackListener<List<TeamMember>>() {
                    @Override
                    public void onCompleted() {
                        // do nothing
                    }

                    @Override
                    public void onError(String msg) {
                        teamDescView.showErrorToast("加载已有成员失败，请重试");
                    }

                    @Override
                    public void onNext(List<TeamMember> teamMembers) {
                        showDataOnView(teamMembers);
                    }
                });
    }

    /**
     * 根据取数情况判断view如何显示.
     *
     * @param teamMembers 团队成员列表
     */
    private void showDataOnView(List<TeamMember> teamMembers) {
        handler.postDelayed(() -> {
            if (teamMembers.isEmpty()) {
                teamDescView.showNoData();
                return;
            }
            teamDescView.showTeamMembers(teamMembers);
        }, 1000);
    }
}
